package datastructures

import (
	"encoding/json"
	"fmt"
	"sort"
)

// DemoSliceOperations 演示切片的高级操作
func DemoSliceOperations() {
	fmt.Println("=== 高级数据结构操作演示 ===")
	fmt.Println("\n--- 切片的高级操作 ---")

	// 创建切片
	numbers := []int{1, 2, 3, 4, 5}
	fmt.Printf("初始切片: %v, 长度: %d, 容量: %d\n", numbers, len(numbers), cap(numbers))

	// 追加元素
	numbers = append(numbers, 6, 7, 8)
	fmt.Printf("追加后切片: %v, 长度: %d, 容量: %d\n", numbers, len(numbers), cap(numbers))

	// 切片操作
	slice1 := numbers[2:5] // 获取索引2到4的元素（不包括5）
	fmt.Printf("切片[2:5]: %v\n", slice1)

	slice2 := numbers[:3] // 获取索引0到2的元素
	fmt.Printf("切片[:3]: %v\n", slice2)

	slice3 := numbers[4:] // 获取索引4到末尾的元素
	fmt.Printf("切片[4:]: %v\n", slice3)

	// 注意：切片是引用类型，修改切片会影响原切片
	slice1[0] = 100
	fmt.Printf("修改slice1后，原切片: %v\n", numbers)
	fmt.Printf("修改slice1后，slice1: %v\n", slice1)

	// 切片的复制
	source := []int{10, 20, 30, 40, 50}
	dest := make([]int, 3) // 创建一个长度为3的目标切片
	n := copy(dest, source)
	fmt.Printf("复制结果: dest=%v, 复制了%d个元素\n", dest, n)

	// 切片的排序
	unsorted := []int{5, 2, 9, 1, 5, 6}
	sorted := make([]int, len(unsorted))
	copy(sorted, unsorted)
	sort.Ints(sorted)
	fmt.Printf("排序前: %v\n", unsorted)
	fmt.Printf("排序后: %v\n", sorted)

	// 删除切片中的元素
	indexToRemove := 2
	numbers = append(numbers[:indexToRemove], numbers[indexToRemove+1:]...)
	fmt.Printf("删除索引%d后的切片: %v\n", indexToRemove, numbers)

	// 切片去重
	duplicates := []int{1, 2, 2, 3, 4, 4, 5}
	unique := removeDuplicates(duplicates)
	fmt.Printf("去重前: %v\n", duplicates)
	fmt.Printf("去重后: %v\n", unique)
}

// removeDuplicates 移除切片中的重复元素
func removeDuplicates(slice []int) []int {
	seen := make(map[int]bool)
	result := []int{}

	for _, item := range slice {
		if !seen[item] {
			seen[item] = true
			result = append(result, item)
		}
	}

	return result
}

// DemoMapOperations 演示映射的高级操作
func DemoMapOperations() {
	fmt.Println("\n--- 映射的高级操作 ---")

	// 创建映射
	person := map[string]interface{}{
		"name":  "张三",
		"age":   30,
		"city":  "北京",
		"email": "zhangsan@example.com",
	}
	fmt.Printf("初始映射: %v\n", person)

	// 访问映射元素
	name, exists := person["name"]
	if exists {
		fmt.Printf("姓名: %v\n", name)
	}

	// 检查键是否存在
	phone, exists := person["phone"]
	if exists {
		fmt.Printf("电话: %v\n", phone)
	} else {
		fmt.Println("电话不存在")
	}

	// 修改映射元素
	person["age"] = 31
	fmt.Printf("修改年龄后: %v\n", person)

	// 添加新元素
	person["phone"] = "13800138000"
	fmt.Printf("添加电话后: %v\n", person)

	// 删除元素
	delete(person, "email")
	fmt.Printf("删除邮箱后: %v\n", person)

	// 遍历映射
	fmt.Println("遍历映射:")
	for key, value := range person {
		fmt.Printf("%s: %v\n", key, value)
	}

	// 映射的长度
	fmt.Printf("映射长度: %d\n", len(person))

	// 嵌套映射
	departments := map[string]map[string]int{
		"研发部": {
			"经理": 1,
			"工程师": 10,
			"实习生": 5,
		},
		"市场部": {
			"经理": 1,
			"专员": 5,
		},
	}
	fmt.Printf("嵌套映射: %v\n", departments)

	// 访问嵌套映射元素
	if rdEngineers, exists := departments["研发部"]["工程师"]; exists {
		fmt.Printf("研发部工程师数量: %d\n", rdEngineers)
	}
}

// User 演示结构体标签的用户结构体
type User struct {
	ID        int    `json:"id" db:"user_id"`
	Username  string `json:"username" db:"username"`
	Email     string `json:"email" db:"email"`
	Password  string `json:"-" db:"password"` // 连字符表示在JSON中忽略此字段
	CreatedAt string `json:"created_at" db:"created_at"`
}

// Product 演示数据库标签的产品结构体
type Product struct {
	ID    int     `db:"product_id"`
	Name  string  `db:"product_name"`
	Price float64 `db:"price"`
	Stock int     `db:"stock_quantity"`
}

// DemoStructTags 演示结构体标签
func DemoStructTags() {
	fmt.Println("\n--- 结构体标签 ---")

	// 创建带标签的结构体实例
	user := User{
		ID:        1,
		Username:  "johndoe",
		Email:     "john@example.com",
		Password:  "secret123", // 这个字段在JSON中会被忽略
		CreatedAt: "2023-01-01T10:00:00Z",
	}

	fmt.Printf("结构体实例: %+v\n", user)

	// 将结构体转换为JSON
	jsonData, err := json.Marshal(user)
	if err != nil {
		fmt.Println("JSON序列化错误:", err)
		return
	}

	fmt.Printf("JSON数据: %s\n", jsonData)

	// 从JSON反序列化到结构体
	var decodedUser User
	if err := json.Unmarshal(jsonData, &decodedUser); err != nil {
		fmt.Println("JSON反序列化错误:", err)
		return
	}

	fmt.Printf("反序列化后的结构体: %+v\n", decodedUser)

	// 演示数据库标签
	product := Product{
		ID:    101,
		Name:  "笔记本电脑",
		Price: 6999.99,
		Stock: 50,
	}

	fmt.Printf("带数据库标签的结构体: %+v\n", product)
	// 在实际应用中，ORM框架会使用这些标签来映射数据库列
}

// DemoCompositeTypes 演示复合类型操作
func DemoCompositeTypes() {
	fmt.Println("\n--- 复合类型操作 ---")

	// 数组的数组（二维数组）
	matrix := [3][3]int{
		{1, 2, 3},
		{4, 5, 6},
		{7, 8, 9},
	}

	fmt.Println("二维数组:")
	for i := 0; i < len(matrix); i++ {
		fmt.Println(matrix[i])
	}

	// 切片的切片（多维切片）
	jagged := [][]int{
		{1, 2, 3},
		{4, 5},
		{6, 7, 8, 9},
	}

	fmt.Println("多维切片:")
	for _, row := range jagged {
		fmt.Println(row)
	}

	// 结构体切片
	students := []struct {
		Name  string
		Age   int
		Grade float64
	}{{
		Name:  "张三",
		Age:   18,
		Grade: 92.5,
	}, {
		Name:  "李四",
		Age:   19,
		Grade: 88.0,
	}, {
		Name:  "王五",
		Age:   18,
		Grade: 95.5,
	}}

	fmt.Println("结构体切片:")
	for _, student := range students {
		fmt.Printf("姓名: %s, 年龄: %d, 成绩: %.1f\n", student.Name, student.Age, student.Grade)
	}
}

// DemoAdvancedDataStructures 展示高级数据结构操作
func DemoAdvancedDataStructures() {
	// 调用各个演示函数
	DemoSliceOperations()
	DemoMapOperations()
	DemoStructTags()
	DemoCompositeTypes()
}